package userPages;
import pages.*;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import database.DBUtils;

/**
 * Servlet implementation class MakeReservation
 */
public class MakeReservation extends HttpServlet {
	
	static private String synchronizer = "sync";
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public MakeReservation() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String id = request.getParameter("id");
		String startTime = request.getParameter("startTime");
		String endTime = request.getParameter("endTime");

		Date startDate, endDate = null;
		
		//System.out.println(endTime);
		//System.out.println(startTime);

		DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");

		if (id == null) {
			//System.out.println("Check 0!");
			response.sendError(403);
			return;
		}
		if (startTime == null) {
			//System.out.println("Check 1!");
			response.sendError(403);
			return;
		}

		if (endTime == null) {
			//System.out.println("Check 2!");
			response.sendError(403);
			return;
		}

		try {
			endDate = formatter.parse(endTime);
		} catch (ParseException e) {
			//System.out.println("Check 3!");
			response.sendError(403);
			return;
		}

		try {
			startDate = formatter.parse(startTime);
		} catch (ParseException e) {
			//System.out.println("Check 4!");
			response.sendError(403);
			return;
		}

		if (!startDate.before(endDate)) {
			//System.out.println("Check 5!");
			response.sendError(403);
			return;
		}
		
		if(startDate.before(Calendar.getInstance().getTime()))
		{
			response.sendError(403);
			return;
		}
		//System.out.println("Add1!");

		reserve(response, id, startDate, endDate, request.getUserPrincipal()
				.getName());

		response.getWriter().flush();
		response.getWriter().close();

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * Perform reservation  - synchronized for all users
	 * @param response
	 * @param id
	 * @param startDate
	 * @param endDate
	 * @param username
	 * @throws IOException
	 */
	 private void reserve(HttpServletResponse response, String id,
			Date startDate, Date endDate, String username) throws IOException {
		 synchronized(synchronizer){
		
		Connection conn = null;
		PreparedStatement selectUserStmt = null, insertStmt = null;
		ResultSet rs = null;
		try {
			conn = DBUtils.getConnection();
			String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";
			SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
			String strEndDate = sdf.format(endDate);
			String strStartDate = sdf.format(startDate);

			String query = "SELECT * FROM instruments as i LEFT OUTER JOIN reservations as r ON ( r.instrumentid = i.id ), permissions as p "
					+ "WHERE i.id = ? && p.userLogin = ? && p.typeID=i.typeID && "
					+ "NOT EXISTS( SELECT * FROM reservations as r2 where i.id = r2.instrumentid && "
					+ "endTime >  ? && starttime < ?);";

			//System.out.println(query);
			//System.out.println(strStartDate);
			//System.out.println(strEndDate);
			//System.out.println(username);
			selectUserStmt = conn.prepareStatement(query);
			selectUserStmt.setString(1, id);
			selectUserStmt.setString(2, username);
			selectUserStmt.setString(3, strStartDate);
			selectUserStmt.setString(4, strEndDate);
			rs = selectUserStmt.executeQuery();
			if (rs == null || !rs.next()) {
				//System.out.println("Empty response");
				response.sendError(500);

			} else {
				//System.out.println("Add!");
				String reservationsTableName = LMUtils.getContextParameterValue(
						getServletContext(), "db.ReservationsTableName");
				insertStmt = conn
						.prepareStatement("INSERT INTO `"
								+ reservationsTableName
								+ "` (`userLogin`, `instrumentID`, `startTime`, `endTime`)"
								+ " VALUES (?, ?, ?, ?);");
				insertStmt.setString(1, username);
				insertStmt.setString(2, id);
				insertStmt.setString(3, strStartDate);
				insertStmt.setString(4, strEndDate);
				//System.out.println("Add!");

				insertStmt.execute();
			}
		} catch (Exception e) {
			//System.out.println(e.getMessage());
			response.sendError(500);
		} finally {
			DBUtils.close(rs);
			DBUtils.close(selectUserStmt);
			DBUtils.close(conn);
		}

		response.getWriter().flush();
		response.getWriter().close();
		 }
	}

}
